<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
  <title>Document</title>
</head>
<style>
  body,
  ul,
  dl,
  dd {
    margin: 0;
    padding: 0;
  }

  ul {
    list-style: none;
  }

  .carousel-container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 10px;
    width: 70em;
    height: auto;
    overflow: hidden;
  }

  .carousel-container .carousel-wrapper {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    transition: margin-left 0.6s;
  }

  .carousel-container .carousel-wrapper li {
    flex: 1;
  }

  .carousel-container .carousel-wrapper li img {
    max-width: 100%;
    height: auto;
  }

  .arrow-left,
  .arrow-right {
    position: absolute;
    top: 50%;
    width: 2em;
    height: 2em;
    border-top: 0.3em solid black;
    border-right: 0.3em solid black;
  }

  .arrow-left:hover,
  .arrow-right:hover {
    cursor: pointer;
  }

  .arrow-left {
    left: 1em;
    border-radius: 2px;
    transform: translateY(-50%) rotate(-135deg);
  }

  .arrow-right {
    right: 1em;
    border-radius: 2px;
    transform: translateY(-50%) rotate(45deg);
  }

  .indicator-container {
    position: absolute;
    bottom: 1em;
    left: 50%;
    transform: translate(-50%);
  }

  .indicator-container .indicator-wrapper {
    display: flex;
    flex-wrap: nowrap;
  }

  .indicator-container .indicator-wrapper .dot {
    flex: 1;
    background: rgba(255, 255, 255, 0.4);
    width: 1.8em;
    height: 1.8em;
    line-height: 1.8em;
    text-align: center;
    margin-right: 0.5em;
    border-radius: 50%;
    user-select: none;
  }

  .indicator-container .indicator-wrapper .dot:hover {
    cursor: pointer;
  }

  .indicator-container .indicator-wrapper .dot.active {
    background-color: orange;
  }
</style>
<body>
<div class="carousel-container">
  <ul class="carousel-wrapper" style="width: 700%;margin-left: -100%">
    <li>
      <img src="./images/slide05.webp" alt=""/>
    </li>
    <li>
      <img src="./images/slide01.jpg" alt=""/>
    </li>
    <li>
      <img src="./images/slide02.webp" alt=""/>
    </li>
    <li>
      <img src="./images/slide03.webp" alt=""/>
    </li>
    <li>
      <img src="./images/slide04.webp" alt=""/>
    </li>
    <li>
      <img src="./images/slide05.webp" alt=""/>
    </li>
    <li>
      <img src="./images/slide01.jpg" alt=""/>
    </li>
  </ul>
  <div class="arrow-left"></div>
  <div class="arrow-right"></div>
  <div class="indicator-container">
    <dl class="indicator-wrapper">
      <dd class="dot active">1</dd>
      <dd class="dot">2</dd>
      <dd class="dot">3</dd>
      <dd class="dot">4</dd>
      <dd class="dot">5</dd>
    </dl>
  </div>
</div>

<script>
  // 自动轮播定时器
  let timer = null;
  // 指示器索引
  let dotIndex = 0;
  //步进值
  let step = 200;
  // 避免点击过快
  let isClick = true;
  // 获取轮播图容器
  let slider = document.querySelector(
    ".carousel-container .carousel-wrapper"
  );
  // 获取所有的轮播图子项
  let slides = slider.querySelectorAll("li");
  // 获取所有的指示器
  let dots = document.querySelectorAll(
    ".indicator-container .indicator-wrapper .dot"
  );
  // 开启自动轮播
  timer = setInterval(dotMove, 2000);

  // 指示器切换
  function dotMove(index = ++dotIndex) {
    dotIndex = index;
    dots.forEach(item => {
      item.classList.remove("active");
    });
    if (dotIndex >= dots.length) {
      slideMove((dots.length + 1) * 100);
      dotIndex = 0;
    } else if (dotIndex < 0) {
      slideMove(0);
      dotIndex = dots.length - 1;
    } else {
      slideMove((dotIndex + 1) * 100);
    }
    dots[dotIndex].classList.add("active");
  }

  // 轮播图切换
  function slideMove(i = step) {
    step = i = Math.abs(i)
    slider.style.marginLeft = -i + "%";
    if (i >= (slides.length - 1) * 100) {
      step = 100
      setTimeout(() => {
        slider.style.transition = "none";
        slider.style.marginLeft = "-100%";
        // 延迟100ms添加过渡效果
        setTimeout(() => {
          slider.style.transition = "margin-left .6s";
        }, 50);
      }, 600);
    } else if (i <= 0) {
      step = (slides.length - 1) * 100
      setTimeout(() => {
        slider.style.transition = "none";
        slider.style.marginLeft = "-500%";
        // 延迟100ms添加过渡效果
        setTimeout(() => {
          slider.style.transition = "margin-left .6s";
        }, 50);
      }, 600);
    }
    step += 100
  }

  document
    .querySelector(".arrow-left")
    .addEventListener("click", function () {
      if (isClick) {
        isClick = false;
        clearInterval(timer);
        dotMove(--dotIndex);
        setTimeout(() => {
          isClick = true;
        }, 800);
      }
    });
  document
    .querySelector(".arrow-right")
    .addEventListener("click", function () {
      if (isClick) {
        isClick = false;
        clearInterval(timer);
        dotMove(++dotIndex);
        setTimeout(() => {
          isClick = true;
        }, 800);
      }
    });
  document
    .querySelector(".indicator-wrapper")
    .addEventListener("click", function (e) {
      let target = e.target;
      if (target.className === "dot") {
        if (isClick) {
          isClick = false;
          let index = parseInt(target.innerText);
          if (dotIndex < index) {
            slideMove(index * 100);
            dotMove(index - 1);
          } else {
            slideMove(-index * 100);
            dotMove(index - 1);
          }
          setTimeout(() => {
            isClick = true;
          }, 800);
        }
      }
    });
  document
    .querySelector(".carousel-container")
    .addEventListener("mouseover", function () {
      clearInterval(timer);
    });
  document
    .querySelector(".carousel-container")
    .addEventListener("mouseout", function () {
      timer = setInterval(dotMove, 2000);
    });
</script>
</body>
</html>
